package com.demo.tool;

import okhttp3.*;
import okhttp3.internal.Util;
import org.apache.commons.text.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * Author: Hardy
 * Date:   2018/7/19 16:09
 * Description:
 **/
public class HttpTool {

    private static final Logger log = LoggerFactory.getLogger(HttpTool.class);

    public static final MediaType FORM_TYPE = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    public static final MediaType JSON_TYPE = MediaType.parse("application/json; charset=utf-8");

    private static final OkHttpClient httpClient = new OkHttpClient.Builder()
            .connectTimeout(10, TimeUnit.SECONDS)
            .writeTimeout(30, TimeUnit.SECONDS)
            .readTimeout(30, TimeUnit.SECONDS)
            .build();

    public static String getHeader(HttpServletRequest request, String name) {
        return request == null ? null : request.getHeader(name);
    }

    public static String getParameter(HttpServletRequest request, String name) {
        return request == null ? null : request.getParameter(name);
    }

    public static String getFullUrl(HttpServletRequest request) {
        StringBuilder requestURL = new StringBuilder(request.getRequestURL().toString());
        String queryString = request.getQueryString();
        if (queryString == null) {
            return requestURL.toString();
        } else {
            return requestURL.append('?').append(queryString).toString();
        }
    }

    public static String requestToStr(HttpServletRequest request, Object o) {
        if ("GET".equals(request.getMethod()))
            return StringTool.formatStr("[Request] url: {}, method: {}", HttpTool.getFullUrl(request), request.getMethod());
        else
            return StringTool.formatStr("[Request] url: {}, method: {}, body: {}", HttpTool.getFullUrl(request), request.getMethod(), JsonTool.toJson(o));
    }

    public static String reponseToStr(HttpServletRequest request, Object o) {
        return StringTool.formatStr("[Response] url: {}, resp: {}", HttpTool.getFullUrl(request), JsonTool.toJson(o));
    }

    public static String get(String url) {
        Request request = new Request.Builder()
                .url(url)
                .get()
                .build();

        String result = null;
        try {
            ResponseBody body = httpClient.newCall(request).execute().body();
            if (body != null) result = StringEscapeUtils.unescapeJava(body.string());
        } catch (IOException e) {
            log.error(StringTool.formatStr("[HTTP_TOOL] call url: {} error: ", url), e);
        }
        return result;
    }

    public static String postJson(String url, Object body) {
        Request request = new Request.Builder()
                .url(url)
                .post(RequestBody.create(JSON_TYPE, JsonTool.toJson(body)))
                .build();

        String result = null;
        try {
            ResponseBody resp = httpClient.newCall(request).execute().body();
            if (resp != null) result = StringEscapeUtils.unescapeJava(resp.string());
        } catch (IOException e) {
            log.error(StringTool.formatStr("[HTTP_TOOL] call url: {}, body: {} error: ", url, JsonTool.toJson(body)), e);
        }
        return result;
    }

    public static String postForm(String url, Map<String, String> form) {
        FormBody.Builder builder = new FormBody.Builder(Util.UTF_8);
        for (String name : form.keySet()) {
            builder.add(name, form.get(name));
        }

        Request request = new Request.Builder()
                .url(url)
                .post(builder.build())
                .build();

        String result = null;
        try {
            ResponseBody resp = httpClient.newCall(request).execute().body();
            if (resp != null) result = StringEscapeUtils.unescapeJava(resp.string());
        } catch (IOException e) {
            log.error(StringTool.formatStr("[HTTP_TOOL] call url: {}, form: {} error: ", url, JsonTool.toJson(form)), e);
        }
        return result;
    }
}
